package SGBox

import (
	. "utils"
)

const (
	EnumBodyType_Static    = 0
	EnumBodyType_Dynamic   = 1
	EnumBodyType_Kinematic = 2
)

type CollisionEventFunc func(*Body)

type Body struct {
	Velocity Vec2
	Pos      Vec2
	Shape    *BoxShape
	Type     int

	localMinX float64
	localMinY float64
	localMaxX float64
	localMaxY float64

	Contacts        *Array
	CollisionEvents *Array
	UserData        interface{}

	World *World
}

func NewBody(shape *BoxShape, bodyType int) *Body {
	retBody := &Body{
		Velocity: Vec2{0, 0},
		Pos:      Vec2{0, 0},
		Shape:    shape,
		Type:     bodyType,
		Contacts: new(Array),
	}

	if retBody.Shape != nil {
		retBody.localMinX = -shape.Width * 0.5
		retBody.localMaxX = shape.Width * 0.5
		retBody.localMinY = -shape.Height * 0.5
		retBody.localMaxY = shape.Height * 0.5
	}
	return retBody
}

func (body *Body) ListenEvent(fn CollisionEventFunc) {
	if body.CollisionEvents == nil {
		body.CollisionEvents = new(Array)
	}
	body.CollisionEvents.Add(fn)
}

func (body *Body) TriggerEvent(cb *Body) {
	if body.CollisionEvents != nil {
		body.CollisionEvents.Each(func(ei interface{}) {
			ei.(CollisionEventFunc)(cb)
		})
	}
}

func (body *Body) MinX() float64 {
	return body.localMinX + body.Pos.X
}

func (body *Body) MinY() float64 {
	return body.localMinY + body.Pos.Y
}

func (body *Body) MaxX() float64 {
	return body.localMaxX + body.Pos.X
}

func (body *Body) MaxY() float64 {
	return body.localMaxY + body.Pos.Y
}

func (body *Body) ContactInfo(otherBody *Body) *Contact {

	if (body.MinY() > otherBody.MaxY()) || (body.MaxY() < otherBody.MinY()) || (body.MaxX() < otherBody.MinX()) || (body.MinX() > otherBody.MaxX()) {
		return nil
	} else {
		retContact := NewContact()
		retContact.BodyA = body
		retContact.BodyB = otherBody
		return retContact
	}
}

func (body *Body) CanMove(otherBody *Body) (TopY, BottomY, LeftX, RightX bool) {
	//BottomY=
	return
}
